#ifndef ENC28J60_H
#define ENC28J60_H


//uint8_t mymac_addr[6] = {0x11,0x22,0x33,0x44,0x55,0xFF};

 //= { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };

#define ENC_MAC0 0xaa
#define ENC_MAC1 0xaa
#define ENC_MAC2 0xaa
#define ENC_MAC3 0xaa
#define ENC_MAC4 0xaa
#define ENC_MAC5 0xaa

// ENC28J60 Control Registers
// Control register definitions are a combination of address,
// bank number, and Ethernet/MAC/PHY indicator bits.
// - Register address   (bits 0-4)
// - Bank number        (bits 5-6)
// - MAC/PHY indicator  (bit 7)

#define ADDR_MASK   0x1F
#define BANK_MASK   0x60
#define SPRD_MASK   0x80

// All-bank registers
#define EIE         0x1B				//Ethernet Interrupt Enable Register
#define EIR         0x1C				//Ethernet Interrupt Request(Flag) Register
#define ESTAT       0x1D				//Ethernet Status Register
#define ECON2       0x1E				//Ethernet Controll Register 2
#define ECON1       0x1F				//Ethernet Controll Register 1

// Bank 0 registers
/*	Buffer */
#define ERDPTL      (0x00|0x00)			//Ethernet Buffer Read Pointer Low Byte
#define ERDPTH      (0x01|0x00)			//Ethernet Buffer Read Pointer High Byte
#define EWRPTL      (0x02|0x00)			//Ethernet Buffer Write Pointer Low Byte
#define EWRPTH      (0x03|0x00)			//Ethernet Buffer Write Pointer High Byte
#define ETXSTL      (0x04|0x00)			//Ethernet TX Buffer Start Pointer Low Byte 
#define ETXSTH      (0x05|0x00)			//Ethernet TX Buffer Start Pointer High Byte
#define ETXNDL      (0x06|0x00)			//Ethernet TX Buffer End Pointer Low Byte
#define ETXNDH      (0x07|0x00)			//Ethernet TX Buffer End Pointer High Byte
#define ERXSTL      (0x08|0x00)			//Ethernet RX Buffer Start Pointer Low Byte
#define ERXSTH      (0x09|0x00)			//Ethernet RX Buffer Start Pointer High Byte
#define ERXNDL      (0x0A|0x00)			//Ethernet RX Buffer End Pointer Low Byte
#define ERXNDH      (0x0B|0x00)			//Ethernet RX Buffer End Pointer High Byte
#define ERXRDPTL    (0x0C|0x00)			//Ethernet RX Buffer Read Pointer Low Byte
#define ERXRDPTH    (0x0D|0x00)			//Ethernet RX Buffer Read Pointer High Byte
#define ERXWRPTL    (0x0E|0x00)			//Ethernet RX Buffer Write Pointer Low Byte
#define ERXWRPTH    (0x0F|0x00)			//Ethernet RX Buffer Write Pointer High Byte
/*	DMA
#define EDMASTL     (0x10|0x00)			//Ethernet DMA Start Low Byte	
#define EDMASTH     (0x11|0x00)			//Ethernet DMA Start High Byte
#define EDMANDL     (0x12|0x00)			//Ethernet DMA END Low Byte
#define EDMANDH     (0x13|0x00)			//Ethernet DMA END High Byte
#define EDMADSTL    (0x14|0x00)			//Ethernet DMA Destination Low Byte
#define EDMADSTH    (0x15|0x00)			//Ethernet DMA Destination High Byte
#define EDMACSL     (0x16|0x00)			//Ethernet DMA Checksum Low Byte 
#define EDMACSH     (0x17|0x00)			//Ethernet DMA Checksum High Byte
*/

// Bank 1 registers
/* Filter */
#define EHT0        (0x00|0x20)			//Ethernet Hash Table Byte 0
#define EHT1        (0x01|0x20)			//Ethernet Hash Table Byte 1
#define EHT2        (0x02|0x20)			//Ethernet Hash Table Byte 2
#define EHT3        (0x03|0x20) 		//Ethernet Hash Table Byte 3
#define EHT4        (0x04|0x20)			//Ethernet Hash Table Byte 4 
#define EHT5        (0x05|0x20)			//Ethernet Hash Table Byte 5
#define EHT6        (0x06|0x20)			//Ethernet Hash Table Byte 6
#define EHT7        (0x07|0x20)			//Ethernet Hash Table Byte 7
#define EPMM0       (0x08|0x20)			//Ethernet Pattern Match Mask Byte 0 
#define EPMM1       (0x09|0x20)			//Ethernet Pattern Match Mask Byte 1
#define EPMM2       (0x0A|0x20)			//Ethernet Pattern Match Mask Byte 2
#define EPMM3       (0x0B|0x20)			//Ethernet Pattern Match Mask Byte 3
#define EPMM4       (0x0C|0x20)			//Ethernet Pattern Match Mask Byte 4
#define EPMM5       (0x0D|0x20)			//Ethernet Pattern Match Mask Byte 5
#define EPMM6       (0x0E|0x20)			//Ethernet Pattern Match Mask Byte 6
#define EPMM7       (0x0F|0x20)			//Ethernet Pattern Match Mask Byte 7
#define EPMCSL      (0x10|0x20)			//Ethernet Pattern Match Checksum Low Byte
#define EPMCSH      (0x11|0x20)			//Ethernet Pattern Match Checksum High Byte
#define EPMOL       (0x14|0x20)			//Ethernet Pattern Match Offset Low Byte
#define EPMOH       (0x15|0x20)			//Ethernet Pattern Match Offset High Byte
#define EWOLIE      (0x16|0x20)			//Ethernet Wake On Lan Interrupt Enable Register
#define EWOLIR      (0x17|0x20)			//Ethernet Wake On Lan Interrupt Request(Flag) Register 
#define ERXFCON     (0x18|0x20)			//Ethernet Receive Filter Control Register
#define EPKTCNT     (0x19|0x20)			//Ethernet Packet Count Register

// Bank 2 registers
#define MACON1      (0x00|0x40|0x80)	//MAC Control Register 1
#define MACON2      (0x01|0x40|0x80)	//MAC Control Register 2
#define MACON3      (0x02|0x40|0x80)	//MAC Control Register 3
#define MACON4      (0x03|0x40|0x80)	//MAC Control Register 4
#define MABBIPG     (0x04|0x40|0x80)	//MAC Back-To-Back Inter-Paket Gap
#define MAIPGL      (0x06|0x40|0x80)	//Non-Back-To-Back Inter-Packet Gap Low Byte
#define MAIPGH      (0x07|0x40|0x80)	//Non-Back-To-Back Inter-Packet Gap High Byte
#define MACLCON1    (0x08|0x40|0x80)	//(Retransmission Maximum)
#define MACLCON2    (0x09|0x40|0x80)	//(Collision Window)
#define MAMXFLL     (0x0A|0x40|0x80)	//Maximum Frame Length Low Byte
#define MAMXFLH     (0x0B|0x40|0x80)	//Maximum Frame Length High Byte
#define MAPHSUP     (0x0D|0x40|0x80)	//MAC-PHY Support Register
#define MICON       (0x11|0x40|0x80)	//MII Control Register
#define MICMD       (0x12|0x40|0x80)	//MII Command Register
#define MIREGADR    (0x14|0x40|0x80)	//MII Register Adress
#define MIWRL       (0x16|0x40|0x80)	//MII Write Data Low Byte
#define MIWRH       (0x17|0x40|0x80)	//MII Write Data High Byte
#define MIRDL       (0x18|0x40|0x80)	//MII Read Data Low Byte
#define MIRDH       (0x19|0x40|0x80)	//MII Read Data High Byte

// Bank 3 registers
/* MAC Adress Register */
#define MAADR1      (0x00|0x60|0x80)	//MAC Adress Byte 1
#define MAADR0      (0x01|0x60|0x80)	//MAC Adress Byte 0
#define MAADR3      (0x02|0x60|0x80)	//MAC Adress Byte 3
#define MAADR2      (0x03|0x60|0x80)	//MAC Adress Byte 2
#define MAADR5      (0x04|0x60|0x80)	//MAC Adress Byte 5
#define MAADR4      (0x05|0x60|0x80)	//MAC Adress Byte 4
/* Build-In Self-Test Controller */ 
#define EBSTSD      (0x06|0x60)			//Ethernet Built-In Seed Register
#define EBSTCON     (0x07|0x60)			//Ethernet Built-In Self-Test Control Register
#define EBSTCSL     (0x08|0x60)			//Ethernet Built-In Self-Test Checksum Low Byte
#define EBSTCSH     (0x09|0x60)			//Ethernet Built-In Self-Test Checksum High Byte

#define MISTAT      (0x0A|0x60|0x80)	//MII Status Register
#define EREVID      (0x12|0x60)			//Ethernet Revision ID
#define ECOCON      (0x15|0x60)			//Ethernet Clock Output Controll Register
#define EFLOCON     (0x17|0x60)			//Ethernet Flow Controll Register
#define EPAUSL      (0x18|0x60)			//Ethernet Pause Timer Value Low Byte
#define EPAUSH      (0x19|0x60)			//Ethernet Pause Timer Value High Byte

// PHY registers
#define PHCON1      0x00				//PHY Control Register 1
#define PHSTAT1     0x01				//PHY Status Register 1
#define PHID1       0x02				//PHY Device ID 1 Register	
#define PHID2       0x03				//PHY Device ID 2 Register
#define PHCON2      0x10				//PHY Control Register 2
#define PHSTAT2     0x11				//PHY Status Register 2
#define PHIE        0x12				//PHY Interrupt Enable Register
#define PHIR        0x13				//PHY Interrupt Request Register
#define PHLCON      0x14				//PHY Control Register


// ENC28J60 EIE Register Bit Definitions
#define EIE_INTIE       0x80
#define EIE_PKTIE       0x40
#define EIE_DMAIE       0x20
#define EIE_LINKIE      0x10
#define EIE_TXIE        0x08
#define EIE_WOLIE       0x04
#define EIE_TXERIE      0x02
#define EIE_RXERIE      0x01
// ENC28J60 EIR Register Bit Definitions
#define EIR_PKTIF       0x40
#define EIR_DMAIF       0x20
#define EIR_LINKIF      0x10
#define EIR_TXIF        0x08
#define EIR_WOLIF       0x04
#define EIR_TXERIF      0x02
#define EIR_RXERIF      0x01
// ENC28J60 ESTAT Register Bit Definitions
#define ESTAT_INT       0x80
#define ESTAT_LATECOL   0x10
#define ESTAT_RXBUSY    0x04
#define ESTAT_TXABRT    0x02
#define ESTAT_CLKRDY    0x01
// ENC28J60 ECON2 Register Bit Definitions
#define ECON2_AUTOINC   0x80
#define ECON2_PKTDEC    0x40
#define ECON2_PWRSV     0x20
#define ECON2_VRPS      0x08
// ENC28J60 ECON1 Register Bit Definitions
#define ECON1_TXRST     0x80
#define ECON1_RXRST     0x40
#define ECON1_DMAST     0x20
#define ECON1_CSUMEN    0x10
#define ECON1_TXRTS     0x08
#define ECON1_RXEN      0x04
#define ECON1_BSEL1     0x02
#define ECON1_BSEL0     0x01
// ENC28J60 MACON1 Register Bit Definitions
#define MACON1_LOOPBK   0x10
#define MACON1_TXPAUS   0x08
#define MACON1_RXPAUS   0x04
#define MACON1_PASSALL  0x02
#define MACON1_MARXEN   0x01
// ENC28J60 MACON2 Register Bit Definitions
#define MACON2_MARST    0x80
#define MACON2_RNDRST   0x40
#define MACON2_MARXRST  0x08
#define MACON2_RFUNRST  0x04
#define MACON2_MATXRST  0x02
#define MACON2_TFUNRST  0x01
// ENC28J60 MACON3 Register Bit Definitions
#define MACON3_PADCFG2  0x80
#define MACON3_PADCFG1  0x40
#define MACON3_PADCFG0  0x20
#define MACON3_TXCRCEN  0x10
#define MACON3_PHDRLEN  0x08
#define MACON3_HFRMLEN  0x04
#define MACON3_FRMLNEN  0x02
#define MACON3_FULDPX   0x01
// ENC28J60 MICMD Register Bit Definitions
#define MICMD_MIISCAN   0x02
#define MICMD_MIIRD     0x01
// ENC28J60 MISTAT Register Bit Definitions
#define MISTAT_NVALID   0x04
#define MISTAT_SCAN     0x02
#define MISTAT_BUSY     0x01
// ENC28J60 PHY PHCON1 Register Bit Definitions
#define PHCON1_PRST     0x8000
#define PHCON1_PLOOPBK  0x4000
#define PHCON1_PPWRSV   0x0800
#define PHCON1_PDPXMD   0x0100
// ENC28J60 PHY PHSTAT1 Register Bit Definitions
#define PHSTAT1_PFDPX   0x1000
#define PHSTAT1_PHDPX   0x0800
#define PHSTAT1_LLSTAT  0x0004
#define PHSTAT1_JBSTAT  0x0002
// ENC28J60 PHY PHCON2 Register Bit Definitions
#define PHCON2_FRCLINK  0x4000
#define PHCON2_TXDIS    0x2000
#define PHCON2_JABBER   0x0400
#define PHCON2_HDLDIS   0x0100
 
// ENC28J60 Packet Control Byte Bit Definitions
#define PKTCTRL_PHUGEEN     0x08
#define PKTCTRL_PPADEN      0x04
#define PKTCTRL_PCRCEN      0x02
#define PKTCTRL_POVERRIDE   0x01
 
// SPI operation codes
#define ENC_READ_CTRL_REG  0x00
#define ENC_READ_BUF_MEM   0x3A
#define ENC_WRITE_CTRL_REG 0x40
#define ENC_WRITE_BUF_MEM  0x7A
#define ENC_BIT_FIELD_SET  0x80
#define ENC_BIT_FIELD_CLR  0xA0
#define ENC_SOFT_RESET     0xFF

 
// buffer boundaries applied to internal 8K ram
//  entire available packet buffer space is allocated
#define TXSTART_INIT    0x0000  // start TX buffer at 0
#define RXSTART_INIT    0x0600  // give TX buffer space for one full ethernet frame (~1500 bytes)
#define RXSTOP_INIT     0x1FFF  // receive buffer gets the rest
 
#define MAX_FRAMELEN    1518    // maximum ethernet frame length

// Ethernet constants
#define ETHERNET_MIN_PACKET_LENGTH  0x3C
//#define ETHERNET_HEADER_LENGTH        0x0E


void enc_init(void);

void enc_setmac(uint8_t* macaddr);

void enc_setbank(uint8_t address);

uint8_t enc_readop(uint8_t opcode, uint8_t address);
void enc_writeop(uint8_t opcode, uint8_t address, uint8_t data);

uint8_t enc_readreg(uint8_t address);
void enc_writereg(uint8_t address, uint8_t data);

uint8_t enc_readphy(uint8_t address);
void enc_writephy(uint8_t address, uint16_t data);

void enc_readbuffer(uint16_t len, uint8_t* data);
void enc_writebuffer(uint16_t len, uint8_t* data);

void enc_writepacket(uint16_t len, uint8_t* packet);
uint16_t enc_readpacket(uint16_t len, uint8_t* packet); 

void enc_sendpacket(uint16_t len, uint8_t* packet);

void enc_pktcnt(void);

extern const uint8_t mymac_addr[6];

#endif		
